package net.tinyportal.portal;

import java.io.IOException;
import java.util.Enumeration;

import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import javax.portlet.PortletModeException;
import javax.portlet.WindowState;
import javax.portlet.WindowStateException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.tinyportal.javax.portlet.TpActionRequest;
import net.tinyportal.javax.portlet.TpActionResponse;
import net.tinyportal.javax.portlet.TpPortletRequest;
import net.tinyportal.javax.portlet.TpRenderRequest;
import net.tinyportal.javax.portlet.TpRenderResponse;
import net.tinyportal.tools.FictiveHttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class PortalAction {
	@Autowired
	HttpServletRequest request;
	
	@Autowired
	HttpServletResponse response;
	
	@Autowired
	TpActionRequest actionRequest;
	
	@Autowired
	TpActionResponse actionResponse;
	
	/**
	 * Logger
	 */
	private static final Log log = LogFactory.getLog(PortalAction.class);

	public void doAction(PortletHolder portletHolder, GenericPortlet portlet) 
			throws WindowStateException, PortletModeException, PortletException, IOException {

//		TpActionRequest actionRequest = new TpActionRequest(portletHolder,request);
//		TpActionResponse actionResponse = new TpActionResponse();

		setWindowState(request, portletHolder);
		setPortletMode(request, portletHolder);
		setPortletParameters(portletHolder, actionRequest);

		try {
			portlet.processAction(actionRequest, actionResponse);
			if (actionResponse.isRedirected())
				response.sendRedirect(actionResponse.getRedirection());
		} catch (IllegalStateException ise) {
			actionResponse.cancelRedirected();
		}
		portletHolder.setActionResponse(actionResponse);

	}


	public void doRefresh(PortletHolder portletHolder, GenericPortlet portlet) throws PortletException, IOException, ServletException {
		//Si une redirection est a faire, on ne fait pas de rendu
		if (portletHolder.getActionResponse()!=null && portletHolder.getActionResponse().isRedirected()) return;
		/*
		 * Calcul du portlet
		 */
		TpRenderRequest TPrequest = (TpRenderRequest)portletHolder.getRenderRequest();
		TpRenderResponse TPresponse = (TpRenderResponse)portletHolder.getRenderResponse();

		RequestDispatcher servletDispatcher;
		portlet.render(TPrequest,TPresponse);
		if (TPresponse.getDispatcher() != null) {

			Enumeration eAttribute = TPrequest.getAttributeNames();
			while (eAttribute.hasMoreElements()) {
				String attribute = (String) eAttribute.nextElement();
				Object value = TPrequest.getAttribute(attribute);
				request.setAttribute(attribute, value);
			}
			servletDispatcher = TPresponse.getDispatcher();
			HttpServletResponse newResponse = new FictiveHttpServletResponse((HttpServletResponse) response, TPresponse);				
			servletDispatcher.include(request, newResponse);
			portletHolder.setContent(newResponse.toString());
		} else {
			portletHolder.setContent(TPresponse.getStringContent());
		}

		try {
//			if (portlet.getPortletConfig().getResourceBundle(request.getLocale()).containsKey("javax.portlet.title"))
				portletHolder.setTitle(TPresponse.getTitle());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void doRender(PortletHolder portletHolder, GenericPortlet portlet) {
		TpRenderRequest TPrequest = (TpRenderRequest)portletHolder.getRenderRequest();
		if (portletHolder.getActionResponse()!=null) 
			TPrequest.getParameterMap().putAll(portletHolder.getActionResponse().getRenderParametersMap());
		setWindowState(request, portletHolder);
		setPortletMode(request, portletHolder);
		setPortletParameters(portletHolder, TPrequest);

		setRequestParameters(request, portletHolder);
	}

	void setPortletParameters(PortletHolder portletHolder, TpPortletRequest portletRequest) {
		String portletId = portletHolder.getPortletId();
		StringBuffer sbParam = new StringBuffer(portletId).append("_param_");
		Enumeration<String> parameterEnum = request.getParameterNames();
		while (parameterEnum.hasMoreElements()) {
			String parameters = (String) parameterEnum.nextElement();
			if (parameters.startsWith(sbParam.toString())) {
				String value = request.getParameter(parameters);
				String parameter = parameters.substring(sbParam.length());
				portletRequest.setParameter(parameter, value);
			}							
		}
	}

	static void setRequestParameters(HttpServletRequest httpRequest, PortletHolder portletHolder) {
		httpRequest.setAttribute("javax.portlet.request", portletHolder.getRenderRequest());
		httpRequest.setAttribute("javax.portlet.response", portletHolder.getRenderResponse());
		httpRequest.setAttribute("javax.portlet.config", portletHolder.getPortletConfig());

	}
	/**
	 * Positionne le mode du portlet en fonction
	 * des paramètres de la requête
	 * @param request
	 * @param portletHolder
	 */
	public void setPortletMode(HttpServletRequest request,PortletHolder portletHolder) {
		String portletId = portletHolder.getPortletId();
		StringBuffer sb = new StringBuffer(portletId).append("_").append("mode");
		String mode = request.getParameter(sb.toString());
		if (mode != null) {
			try {
				PortletMode portletMode = new PortletMode(mode);
				portletHolder.setPortletMode(portletMode);
			} catch (PortletModeException pme) {
				pme.printStackTrace();
			}
		}
	}

	/**
	 * Positionne le mode du portlet en fonction
	 * des paramètres de la requête
	 * @param request
	 * @param portletHolder
	 */
	public void setWindowState(HttpServletRequest request, PortletHolder portletHolder) {
		String portletId = portletHolder.getPortletId();
		StringBuffer sb = new StringBuffer(portletId).append("_").append("state");
		String state = request.getParameter(sb.toString());
		if (state != null) {
			try {
				WindowState windowState = new WindowState(state);
				portletHolder.setWindowState(windowState);
			} catch (WindowStateException wse){
				wse.printStackTrace();
			}
		}
	}


}
